package com.feiyuan.modules.sys.service.impl;

import com.feiyuan.common.exception.FeiyuanException;
import com.feiyuan.common.utils.JWTUtils;
import com.feiyuan.common.utils.Sha256Utils;
import com.feiyuan.modules.sys.service.RoleMenuService;
import com.feiyuan.modules.sys.service.UserRoleService;
import com.feiyuan.modules.sys.vo.RoleMenuVO;
import com.feiyuan.modules.sys.vo.UserRoleVO;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.feiyuan.common.utils.PageUtils;
import com.feiyuan.common.utils.Query;

import com.feiyuan.modules.sys.mapper.UserDao;
import com.feiyuan.modules.sys.entity.UserEntity;
import com.feiyuan.modules.sys.service.UserService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;


@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements UserService {

    private Logger logger = LoggerFactory.getLogger(UserService.class);

    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private RoleMenuService roleMenuService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String userName = (String) params.get("userName");
        String phone = (String) params.get("phone");
        String email = (String) params.get("email");
        String name = (String) params.get("name");
        IPage<UserEntity> page = this.page(
                new Query<UserEntity>().getPage(params),
                new QueryWrapper<UserEntity>().like(StringUtils.isNotEmpty(userName), "user_name", userName)
                        .like(StringUtils.isNotEmpty(phone), "phone", phone)
                        .like(StringUtils.isNotEmpty(email), "email", email)
                        .like(StringUtils.isNotEmpty(name), "name", name)
        );

        return new PageUtils(page);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveUser(UserEntity user) {
        /**
         * 进行校验:
         * 1.校验手机号不能重复
         * 2.校验邮箱不能重复
         * 3.用户名不能重复
         * 4.密码加密操作
         */
        // 3.用户名不能重复
        if (StringUtils.isEmpty(user.getUserName())) {
            throw new FeiyuanException("用户名不能为空!", 500);
        }
        UserEntity userName = baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("user_name", user.getUserName()));
        if (userName != null) {
            throw new FeiyuanException("用户名重复了，请重新填写!", 500);
        }

        // 1.校验手机号不能重复
        if (StringUtils.isNotEmpty(user.getPhone())) {
            UserEntity phone = baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("phone", user.getPhone()));
            if (phone != null) {
                throw new FeiyuanException("手机号重复了，请重新填写!", 500);
            }
        }

        // 2.校验邮箱不能重复
        if (StringUtils.isNotEmpty(user.getEmail())) {
            UserEntity email = baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("email", user.getEmail()));
            if (email != null) {
                throw new FeiyuanException("邮箱重复了，请重新填写!", 500);
            }
        }

        // 4.密码加密操作
        if (StringUtils.isEmpty(user.getPassword())) {
            throw new FeiyuanException("密码不能为空!", 500);
        }
        String pwd = Sha256Utils.encryption(user.getPassword());
        user.setPassword(pwd);

        baseMapper.insert(user);

        // 5.保存用户和角色的关系
        if (!CollectionUtils.isEmpty(user.getRoleIds())) {
            userRoleService.saveUserRole(user.getId(), user.getRoleIds());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateByIdUser(UserEntity user) {
        UserEntity userEntity = baseMapper.selectById(user.getId());

        // 如果手机号改变了，校验手机号是否重复
        if (StringUtils.isNotEmpty(user.getPhone()) && !user.getPhone().equals(userEntity.getPhone())) {
            UserEntity phone = baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("phone", user.getPhone()));
            if (phone != null) {
                throw new FeiyuanException("手机号重复了，请重新填写!", 500);
            }
        }

        // 如果邮箱改变了，校验邮箱是否重复
        if (StringUtils.isNotEmpty(user.getEmail()) && !user.getEmail().equals(userEntity.getEmail())) {
            UserEntity email = baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("email", user.getEmail()));
            if (email != null) {
                throw new FeiyuanException("邮箱重复了，请重新填写!", 500);
            }
        }

        // 密码加密
        if (StringUtils.isNotEmpty(user.getPassword()) && !user.getPassword().equals(userEntity.getPassword())) {
            String pwd = Sha256Utils.encryption(user.getPassword());
            user.setPassword(pwd);
        }
        baseMapper.updateById(user);

        // 修改关联的角色
        // 通过用户ID查询是否有角色信息
        if (!CollectionUtils.isEmpty(user.getRoleIds())) {
            userRoleService.selectIsRoles(user);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeByIdsUser(List<Long> userIds) {
        // 删除用户的同时需要删除关联的角色信息
        if (this.removeByIds(userIds)) {
            userRoleService.deleteUserRole(userIds);
        }
    }

    @Override
    public Object login(Map<String, Object> map) {
        String userName = (String) map.get("userName");
        String password = (String) map.get("password");
        if (StringUtils.isEmpty(userName)) {
            throw new FeiyuanException("用户名不能为空!", 500);
        }
        if (StringUtils.isEmpty(password)) {
            throw new FeiyuanException("密码不能为空!", 500);
        }
        // 查询是否存在此用户
        UserEntity user = baseMapper.selectOne(new QueryWrapper<UserEntity>().eq("user_name", userName));
        if (user == null) {
            throw new FeiyuanException("用户名输入错误，请重新输入!", 500);
        }

        // 比较密码
        String pwd = Sha256Utils.encryption(password);
        if (!pwd.equals(user.getPassword())) {
            throw new FeiyuanException("密码输入错误，请重新输入!", 500);
        }

        // 返回token
        String token = JWTUtils.getJwtToken(user.getId().toString(), userName);
        logger.info("this is token:" + token);
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("user", user);
        resultMap.put("token", token);
        return resultMap;
    }

    @Override
    public Object info(HttpServletRequest request) {
        String userId = JWTUtils.getMemberIdByJwtToken(request);
        UserEntity userEntity = baseMapper.selectById(userId);

        Map<String, Object> map = new HashMap<>();
        map.put("user", userEntity);
        map.put("name", userEntity.getUserName());
        map.put("avatar", "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png");

        // 查询角色
        List<UserRoleVO> userRoleVos = userRoleService.selectRoleList(userId);
        StringBuilder sbRoleCode = new StringBuilder();
        StringBuilder sbRoleId = new StringBuilder();
        if (!CollectionUtils.isEmpty(userRoleVos)) {
            for (UserRoleVO userRoleVo : userRoleVos) {
                sbRoleCode.append(userRoleVo.getRoleCode()).append(",");
                sbRoleId.append(userRoleVo.getRoleId()).append(",");
            }
        }
        UserRoleVO userRoleVO = new UserRoleVO();
        userRoleVO.setRoleCodes(sbRoleCode.toString());
        userRoleVO.setRoleIds(sbRoleId.toString());
        userRoleVO.setUserId(userEntity.getId());

        // 查询权限
        List<RoleMenuVO> roleMenuAll = new ArrayList<>();
        for (String roleId : sbRoleId.toString().split(",")) {
            List<RoleMenuVO> roleMenuVOS = roleMenuService.selectMenuList(roleId);
            roleMenuAll.addAll(roleMenuVOS);
        }
        Set<RoleMenuVO> roleMenuSet = new HashSet<>(roleMenuAll);
        List<RoleMenuVO> permissions = new ArrayList<>(roleMenuSet);
        userRoleVO.setPermissions(permissions);

        map.put("role", userRoleVO);
        return map;
    }

    @Override
    public UserEntity getByIdInfo(Long id) {
        UserEntity userEntity = baseMapper.selectById(id);
        // 查询角色信息
        List<Long> roleIds = userRoleService.selectByUserId(id);
        userEntity.setRoleIds(roleIds);
        return userEntity;
    }

}